package com.bml.architect.spring.ack;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;

/**
 * 在rabbit:listener-container标签中设置acknowledge属性，设置ack方式 none：自动确认，manual：手动确认
 *
 * 如果在消费端没有出现异常，则调用channel.basicAck(deliveryTag,false);方法确认签收消息
 *
 * 如果出现异常，则在catch中调用 basicNack或 basicReject，拒绝消息，让MQ重新发送消息。
 */

/**
 * 在<rabbit:listener-container> 中配置 prefetch属性设置消费端一次拉取多少消息
 *
 * 消费端的确认模式一定为手动确认。acknowledge="manual"
 */
public class AckListener implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {

        //消息ID
        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try{
            String msg = new String(message.getBody());
            System.out.println("接受到的消息："+msg);
            System.out.println("业务处理中...");
            Thread.sleep(500);
            //正常签收
            //第二个参数false的意思就是说只签收本次消息，true表示签收之前的所有未签收的
            channel.basicAck(deliveryTag,false);
            System.out.println("处理完成");

        }catch (Exception ce){
            //第三个参数：requeue：重回队列。如果设置为true，则消息重新回到queue，broker会重新发送该消息给消费端
            channel.basicNack(deliveryTag,false,true);
        }

    }


}
